


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
// 大年初三
    
//ts中类的修饰符  (访问类型)
        //1public 2pricate 3protected 这三个关键字      
        //public     修饰的属性和方法是共有的   可以在任何地方被访问到   默认所有的属性或方法都是public (即准许在类的内部和外部调用) 
        //private    修饰的属性或方法是私有的   不能声明它的类外面访问                                (即只准许在类的内部调用 外部不准许)
        //protected  修饰的属性或方法是受保护的 它和private类似                                         (外部访问报错的)
        //demo1 
        //创建Person
        class Person{
                name = "三儿",  
               private age = 18,        //注意这添加private那么在外面 不可以访问的  //注意一但父类将子类定义成私有的之后 子类就不可以进行访问了(继承) 
               protected sex = "牲口",  //父类的属性定义为受保护的 可以在子类里面进行访问 同意不可以在子类外面访问 
               say(){
                        console.log("my name"+this.name+"me age"+this.age)
                }
        }
        //创建Person的实例 
        var p = Person()
        p.say()
        console.log(p.name)     //属性都是可以再外面访问到了    
                                //当一个类成员 变量没有修饰的时候 外界是可以访问的 默认就是public进行修饰 
        console.log(p.age)      //报错  //不可访问的  (上面+provate属性只能再类的内部访问)            
        
        //继承父级 
        //创建child子类 
        class Child extends Person{
                callParent(){
                        console.log(super.sex)   //在这里sex定义为protected 只可以在子类内部使用的 外部不可以用 
                    super.say() //通过super关键字 调用父级     (可以使用super关键字，它代表父类中的方法)
                    super.name   
                }
                static test(){
                        console.log("static test是一个静态方法")
                }
        }
        var c = new Child()
        c.callParent()          //在这里调用callParent ……父级的super.say() super.name 执行就 
        console.log(c.name)     //子类继承父类，子类就可以访问到父类的公开属性&方法 (即没有办法直接获取到父类私有的属性&受保护的属性)
        console.log(c.say())    //
        console.log(Child.test())//类的静态方法里面 不准许用this 


//ts中类的概念和使用 
        //注意ts中类的概念和es6 大部分相同 额外增加了新特性 
        //使用关键字 class  
        calss Lady{
            content = "Hi 大哥",
            sayHelow(){
                return this.conent;
            }
        }
        const goddess = new Lady();
        console.log(sayHelow());
        //类的继承 
        //ts 中继承和es6中继承一样 关键字extends 
        //在这里再写一个 xiaojj的类 然后继承Lady类 在xiaojj类里面加一个新的方法 saylove 
        calss Lady{
            content = "Hi 大哥",
            sayHelow(){
                return this.conent;
            }
        }
        class xiaojj extends Lady {
            saylove(){
                return "i love you"
            }
        }
        const goddess = new xiaojj();
        console.log(goddess.sayHelow)  //两个都是可以执行的 这说明继承起作用了 
        console.log(goddess.saylove)

        //类的重写 
        //重写 即子类可以重新编写父类里面的代码 
        class xiaojj extends Lady {
        saylove() {
            return "I love you!";
        }
        sayHello() {
            return "Hi , honey!";
        }
        }      
        
        //super 关键字的使用  
        //想使用Lady类中说的话 在后面加上你好 这时候就可以使用super关键字，它代表父类中的方法
        class xiaojj extends Lady {
        sayLove() {
            return "I love you!";
        }
        sayHello() {
            return super.sayHello() + "。你好！";
        }
        }

        //类的构造函数  
        //构造函数的关键字时constructor  
        //类的里边定义一个name，name并不给他值,然后在new出对象的时候，直接通过传递参数的形式，给name赋值，并打印出来
        class Person{
                public name:string;
                constructor(name:string){
                        this.name = name 
                }
        }
        const person = new Person("东东");       
        console.log(person.name)                //打印东东 

        //下面时简化的写法 这种写法就相当于定义了一个name 然后在构造函数里进行赋值 
        class Person{
                constructor(public name:string){}
        }   
        const person = new Person("东东")
        console.log(person.name)

        //类 继承的构造器写法 demo 
        class Person{
                constructor(public name:string){}
        }
        class Teacher extends Person {
                constructor(public age:number)
                super("东东")
        }
        const teacher = new Teacher(18)
        console.log(teacher.age)
        console.log(teacher.name)
        //原则 在子类写构造函数时 必须用super()调用父类的构造函数 如果需要传值 也必须进行传值操作 
        //即父类没有构造函数 子类也要使用super()进行调用 否则也报错 
        class Person{}
        class Teacher extends Person{
        constructor(public age:number){
                super()
        }
        }
        const teacher = new Teacher(18)
        console.log(teacher.age)

        
//类的Getter和Setter
        //dmeo 一个xjj的类 里面有它的年龄 不要别人知道 
        class xjj{
                constructor(provide _age:number){}
        }
        //注意 如果想知道xjj的_age年龄 
        //必须是通过getter属性 getter属性的关键字时get 后面跟类似方法东西age(){} 注意它不是方法 归根结底韩式属性  
        class Xiaojiejie {
        constructor(private _age:number){}
                get age(){
        return this._age
        }
        }
        const dajiao = new Xiaojiejie(28)
        console.log(dajiao.age)             //28
        //这样写是不恶心讷 哈 精华在这getter里 我们可以对_age进行处理 
        //比如偷偷的减少10岁(赋值运算&业务逻辑操作)  看代码 
        class Xiaojiejie {
            constructor(private _age:number){}
            get age(){
                    return this._age-10
            }
        }
        //是不是从28的老阿姨 一下子log出18来了 
        //至此 理解到private&getter的用处 
        
        //即_age是私有的 那类的外部无法改变 所以这个时候考虑用setter属性改变 看代码 
        class Xiaojiejie {
                constructor(private _age:number){}
                get age(){
                        return this._age-10
                }
                set age(age:number){
                        this._age=age
                }
        }
        const dajiao = new Xiaojiejie(28)
        dajiao.age=60 
        console.log(dajiao.age)  //50 
        //setter也可以保护私有变量 我们在setter里再给它加200岁 
        set age(){
                this._age=age+3
        }
        //到此getter&setter的使用 和private访问类型意义 

//类中的static 
        //学习类 要使用这个类的实例 就要先New出来(),  当然这个是常规的 还有捷径噢 
        //demo常规 
        class Girl{
                sayLove(){
                        return "i love you";
                }
        }
        const Girl = new Girl();
        console.log(Girl.sayLove());
        //但是现在不想new出对象 直接使用这个方法 ts为你提供了快捷方式 
        //用static声明的属性&方法 不需要进行声明对象 可直接使用 
        class Girl {
                static sayLove(){
                        return "i love you";
                }
        }
        console.log(Girl.sayHello)

        //至此 prvate的使用意义 getter&setter属性 静态修饰符static这样就不用new出对象 可直接使用类的方法了 

//类的只读属性  
        //使用readonly 关键字  
        //比如我现在有一个需求，就是在实例化对象时赋予的名字，以后不能再更改了，也就是我们常说的只读属性。
        //也就是说 后续更改不行的 报错

        //抽象类的使用  
        //抽象类的关键字 abstract 抽象方法也是 abstract 接上面的Girl写个抽象类  
</script>